Skip to content

refactor(architecture): separate server, test, and pure utils to fix CI errors#96

Merged
cameroncooke merged 8 commits into
mainfrom
fix/module-import-bug
Aug 17, 2025
Merged

refactor(architecture): separate server, test, and pure utils to fix CI errors#96
cameroncooke merged 8 commits into
mainfrom
fix/module-import-bug

Conversation

@cameroncooke
Copy link
Copy Markdown
Collaborator

@cameroncooke cameroncooke commented Aug 15, 2025

Summary

This PR introduces a major architectural refactoring to resolve persistent "module is already linked" errors in CI tests. It establishes clear boundaries between server infrastructure, test utilities, and pure utilities, preventing test code from importing and initializing production server components like Sentry.

Beyond fixing the CI failures, this change significantly improves code quality by eliminating over 580 lines of duplicated code, standardizing environment variables, and resolving numerous TypeScript and ESLint errors.

Background/Details

Since the Sentry v10 integration, our CI pipeline has been plagued by 74 "module is already linked" errors, occurring exclusively on the Ubuntu runner. The root cause was an architectural flaw where our central src/utils/index.ts barrel file exported both test utilities and production server code.

This created a problematic import chain:
Testssrc/utils/index.tssrc/server/ code → Sentry Instrumentation

As a result, test suites inadvertently initialized the entire server stack, leading to module loading conflicts within Vitest's vmThreads environment on Linux.

Solution

This PR implements a robust, multi-faceted solution:

  1. Architectural Separation:

    • src/server/: A new dedicated directory for all server-side infrastructure, including tool-registry.ts, dynamic-tools.ts, generated-plugins.ts, and the new server bootstrap logic.
    • src/test-utils/: A new directory for test-only code. It contains pure mock executors and test execution logic (test-execution.ts) that have no dependencies on the production server.
    • src/utils/: This directory has been purified to contain only side-effect-free, context-agnostic utilities. It no longer exports any server or test-specific code.
  2. Lazy Sentry Integration & Async Server Bootstrap:

    • The server now bootstraps asynchronously (createServer in src/server/bootstrap.ts).
    • Sentry is loaded lazily using a dynamic import() in src/server/instrumentation.ts, ensuring it is only imported in production environments and never by tests.
    • The Sentry opt-out environment variable has been standardized to XCODEBUILDMCP_SENTRY_DISABLED.
  3. DRY Principle & Code Refactoring:

    • src/utils/axe-command.ts: A new shared utility was created to handle all axe command executions. This eliminated ~580 lines of duplicated logic across 10+ UI testing tools.
    • src/utils/system-info.ts: A new shared module was created to centralize system/environment discovery logic, now used by both the doctor tool and Sentry instrumentation.
  4. Code Quality and Build Fixes:

    • Resolved 3 TypeScript compilation errors.
    • Fixed 16 ESLint violations related to unsafe types and other best practices.
    • Updated eslint.config.js to correctly ignore all generated-*.ts files, preventing linting errors in auto-generated code.

Testing

  • CI Verification: The primary validation is the successful resolution of all 74 "module is already linked" errors. The CI pipeline now passes consistently on Ubuntu runners.
  • Manual Regression Testing: Performed comprehensive end-to-end testing of all 59 MCP tools using the Reloaderoo inspector client. This verified that the extensive refactoring did not introduce any regressions in tool functionality.
  • Unit Test Updates: Updated unit tests, particularly for the doctor tool, to align with the new dependency injection patterns and module structure.

Notes

This is a foundational architectural improvement that not only fixes a critical CI issue but also makes the codebase more modular, maintainable, and resilient against future contamination between test and production code paths.

Summary by CodeRabbit

  • New Features

    • Simulator tools accept simulatorName in addition to UUID; unified simulator launch accepts either.
  • Refactor

    • Several simulator and macOS tool names consolidated/renamed; redundant launch variant removed.
  • Documentation

    • Streamlined tools list and counts (59 canonical, 81 total); removed legacy "Key Changes" section and updated examples/last-updated metadata.
  • Tests

    • New deterministic mock executor/file-system utilities added; tests updated to use them.
  • Chores

    • Removed legacy verification documents.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant